package org.lucava.boatskeeper.client;

import org.lucava.boatskeeper.client.event.boat.AddBoatEvent;
import org.lucava.boatskeeper.client.event.boat.AddBoatEventHandler;
import org.lucava.boatskeeper.client.event.boat.BoatUpdatedEvent;
import org.lucava.boatskeeper.client.event.boat.BoatUpdatedEventHandler;
import org.lucava.boatskeeper.client.event.boat.EditBoatCancelledEvent;
import org.lucava.boatskeeper.client.event.boat.EditBoatCancelledEventHandler;
import org.lucava.boatskeeper.client.event.boat.EditBoatEvent;
import org.lucava.boatskeeper.client.event.boat.EditBoatEventHandler;
import org.lucava.boatskeeper.client.presenter.BoatsPresenter;
import org.lucava.boatskeeper.client.presenter.EditBoatPresenter;
import org.lucava.boatskeeper.client.presenter.EditUserPresenter;
import org.lucava.boatskeeper.client.presenter.Presenter;
import org.lucava.boatskeeper.client.presenter.UsersPresenter;
import org.lucava.boatskeeper.client.view.BoatsView;
import org.lucava.boatskeeper.client.view.EditBoatView;
import org.lucava.boatskeeper.client.view.EditUserView;
import org.lucava.boatskeeper.client.view.UsersView;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.HasWidgets;

public class AppController implements Presenter, ValueChangeHandler<String> {
	private final HandlerManager eventBus;
	private final BoatsKeeperServiceAsync rpcService;
	private HasWidgets container;

	public AppController(BoatsKeeperServiceAsync rpcService,
			HandlerManager eventBus) {
		this.eventBus = eventBus;
		this.rpcService = rpcService;
		bind();
	}

	private void bind() {
		History.addValueChangeHandler(this);

		eventBus.addHandler(AddBoatEvent.TYPE, new AddBoatEventHandler() {
			public void onAddBoat(AddBoatEvent event) {
				doAddNewBoat();
			}
		});

		eventBus.addHandler(EditBoatEvent.TYPE, new EditBoatEventHandler() {
			public void onEditBoat(EditBoatEvent event) {
				doEditBoat(event.getId());
			}
		});

		eventBus.addHandler(EditBoatCancelledEvent.TYPE,
				new EditBoatCancelledEventHandler() {
					public void onEditBoatCancelled(EditBoatCancelledEvent event) {
						doEditBoatCancelled();
					}
				});

		eventBus.addHandler(BoatUpdatedEvent.TYPE,
				new BoatUpdatedEventHandler() {
					public void onBoatUpdated(BoatUpdatedEvent event) {
						doBoatUpdated();
					}
				});
	}

	private void doAddNewBoat() {
		History.newItem("addBoat");
	}

	private void doEditBoat(Integer id) {
		History.newItem("editBoat", false);
		Presenter presenter = new EditBoatPresenter(rpcService, eventBus,
				new EditBoatView(), id);
		presenter.go(container);
	}

	private void doEditBoatCancelled() {
		History.newItem("listBoat");
	}

	private void doBoatUpdated() {
		History.newItem("listBoat");
	}

	private void doAddNewUser() {
		History.newItem("addUser");
	}

	private void doEditUser(Integer id) {
		History.newItem("editUser", false);
		Presenter presenter = new EditUserPresenter(rpcService, eventBus,
				new EditUserView(), id);
		presenter.go(container);
	}

	private void doEditUserCancelled() {
		History.newItem("listUser");
	}

	private void doUserUpdated() {
		History.newItem("listUser");
	}

	public void go(final HasWidgets container) {
		this.container = container;

		if ("".equals(History.getToken())) {
			History.newItem("listBoat");
		} else {
			History.fireCurrentHistoryState();
		}
	}

	public void onValueChange(ValueChangeEvent<String> event) {
		String token = event.getValue();

		if (token != null) {
			Presenter presenter = null;

			// Partie spécifique aux bateaux
			if (token.equals("listBoat")) {
				presenter = new BoatsPresenter(rpcService, eventBus,
						new BoatsView());
			}
			if (token.equals("addBoat")) {
				presenter = new EditBoatPresenter(rpcService, eventBus,
						new EditBoatView());
			}
			if (token.equals("editBoat")) {
				presenter = new EditBoatPresenter(rpcService, eventBus,
						new EditBoatView());
			}

			// Partie spécifique aux utilisateurs
			if (token.equals("listUser")) {
				presenter = new UsersPresenter(rpcService, eventBus,
						new UsersView());
			}
			if (token.equals("addUser")) {
				presenter = new EditUserPresenter(rpcService, eventBus,
						new EditUserView());
			}
			if (token.equals("editUser")) {
				presenter = new EditUserPresenter(rpcService, eventBus,
						new EditUserView());
			}

			if (presenter != null) {
				presenter.go(container);
			}
		}
	}
}
